﻿using System;
using System.ComponentModel;
using System.Net;
using System.Net.Mail;
using System.Runtime.InteropServices;

namespace Co9320.NamaAlert.Extension.Model
{
    class SendMail
    {
        private ISetting setting;

        public SendMail(ISetting setting)
        {
            this.setting = setting;
        }

        /// <summary>
        /// メールを送信する
        /// </summary>
        /// <param name="title"></param>
        /// <param name="body"></param>
        public void Send(string title, string body)
        {
            Send(title, body, null);
        }
        /// <summary>
        /// メールを送信する
        /// </summary>
        /// <param name="title"></param>
        /// <param name="body"></param>
        /// <param name="action"></param>
        public void Send(string title, string body, Action<AsyncCompletedEventArgs> action)
        {
            if(setting.ToMailAddress == "" || setting.FromMailAddress == "" || setting.SmtpServer == "")
            {
                throw new Exception("メールアドレスが設定されていません。");
            }

            MailMessage msg = new MailMessage();
            
            try
            {
                var encoding = System.Text.Encoding.GetEncoding(setting.TextEncoding);
                msg.SubjectEncoding = encoding;
                msg.BodyEncoding = encoding;
                msg.From = new MailAddress(setting.FromMailAddress, "NamaAlert Mail-Plugin", encoding);
                msg.To.Add(new MailAddress(setting.FromMailAddress, setting.ToMailAddress, encoding));

                msg.Subject = title;
                msg.Body = body;

                SmtpClient client = new SmtpClient();
                client.Host = setting.SmtpServer;
                client.Port = setting.SmtpPort;
                client.EnableSsl = setting.SmtpUseSsl;

                // ユーザー名とパスワードを設定する
                if (setting.SmtpUseAuth)
                {
                    IntPtr pass = Marshal.SecureStringToBSTR(setting.SmtpPassword);
                    client.Credentials = new NetworkCredential(setting.SmtpUserName, Marshal.PtrToStringAuto(pass));
                }

                // メール送信後のイベントを設定 
                client.SendCompleted += new SendCompletedEventHandler(client_SendCompleted);

                // 非同期でメール送信
                client.SendAsync(msg, new UserState(msg, action));
            }
            catch (Exception)
            {
                throw;
            }
        }

        void client_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            UserState state = (UserState)e.UserState;
            state.Message.Dispose();
            if(state.Action != null)
                state.Action(e);
        }

        class UserState
        {
            public MailMessage Message
            {
                get;
                private set;
            }
            public Action<AsyncCompletedEventArgs> Action
            {
                get;
                private set;
            }

            public UserState(MailMessage msg, Action<AsyncCompletedEventArgs> action)
            {
                this.Message = msg;
                this.Action = action;
            }
        }
    }
}
